home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / Portable Patmos / src / portable kernel / mac / syscalls.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-30  |  32.9 KB  |  1,324 lines  |  [TEXT/KAHL]

  1. #ifdef THINK_C
  2. #include <LoMem.h>
  3. #include <THINK.h>
  4. #define get_time() TimeLM
  5. #define get_ticks() Ticks
  6. #else
  7. #include <Types.h>
  8. #include <Errors.h>
  9. #include <Memory.h>
  10. #include <OSUtils.h>
  11. #include <SegLoad.h>
  12. #include <Quickdraw.h>
  13. #include <Files.h>
  14. #include <Menus.h>
  15. #include <Fonts.h>
  16. #include <Resources.h>
  17. #include <GestaltEqu.h>
  18. #include <Traps.h>
  19. #include <Aliases.h>
  20. #include <Packages.h>
  21. #include <Processes.h>
  22. #include <AppleEvents.h>
  23. #include <ToolUtils.h>
  24. #include <SysEqu.h>
  25. #define get_time() (*(long *)TimeLM)
  26. #define get_ticks() (*(long *)Ticks)
  27. enum {FALSE,TRUE};
  28. #endif
  29. #include <GestaltEqu.h>
  30. #include <ToolUtils.h>
  31. #include <Retrace.h>
  32. #include <OSUtils.h>
  33. #include <stdio.h>
  34. #include <errno.h>
  35. #include <string.h>
  36. #include <stdlib.h>
  37. #include <dirent.h>
  38. #include <fcntl.h>
  39. #include <utime.h>            
  40. #include <unistd.h>
  41. #include <sys/uio.h>
  42. #include <sys/mman.h>
  43. #include <sys/stat.h>
  44. #include <sys/syscall.h>
  45. #include <sys/ioctl.h>
  46. #include <sys/syslimits.h>
  47. #include <sys/time.h>
  48. #include <sys/resource.h>
  49. #include <sys/signal.h>
  50. #include <sys/signalvar.h>
  51. #include <sys/ptrace.h>
  52. #include <sys/wait.h>
  53. #include <sys/socket.h>
  54. #include "crtlocal.h"
  55. #include "proc_mmu.h"
  56.  
  57. struct mmu *proc_tab[maxproc];
  58.  
  59. void sched(void)
  60.     {
  61.     static long real_time = 0;
  62.     static int proc_no = 0;
  63.     long now = get_ticks();
  64.     int must_swap = 0;
  65.     if (crp) crp->ticks += now-old_ticks;
  66.     do
  67.         {
  68.         int cnt;
  69.         if ((now-real_time > kInterval) || (now < real_time))
  70.             {
  71.             real_time = now;
  72.             must_swap = 1;
  73.             checkevents();
  74.             }
  75.         if (interrupt && (crp->state=='R'))
  76.             {
  77.             interrupt = 0;
  78.             if (crp->trace_me)
  79.                 {
  80.                 crp->state = 'T';
  81.                 crp->result = W_STOPCODE(SIGINT);
  82.                 }
  83.             else
  84.                 {
  85.                 crp->state = 'X';
  86.                 crp->result = SIGINT;
  87.                 }
  88.             must_swap = 1;
  89.             }
  90.         cnt = 2*sizeof(proc_tab)/sizeof(*proc_tab);
  91.         if (must_swap || !crp || (crp->state!='D')) do
  92.             {
  93.             proc_no = (proc_no+1)%(sizeof(proc_tab)/sizeof(*proc_tab));
  94.             }
  95. #if 0
  96.         while (cnt-- && (!proc_tab[proc_no]  || ((cnt > 0*sizeof(proc_tab)/sizeof(*proc_tab)) && ((proc_tab[proc_no]->state=='W')||(proc_tab[proc_no]->state=='Z'))) ));
  97. #else
  98.         while (cnt-- && !proc_tab[proc_no]);
  99. #endif
  100.         if (crp != proc_tab[proc_no])
  101.             {
  102.             if (crp && crp->savestack)
  103.                 {
  104.                 int usp = crp->registers.save[15];
  105.                 crp->savestack = xrealloc(crp->savestack, crp->stack_limit-usp);
  106.                 kumemcpy(crp, crp->savestack, usp, crp->stack_limit-usp);
  107.                 }
  108.             crp = proc_tab[proc_no];
  109.             if (crp && crp->savestack)
  110.                 {
  111.                 int usp = crp->registers.save[15];
  112.                 ukmemcpy(crp, usp, (void *)(crp->savestack), crp->stack_limit-usp);
  113.                 }
  114.             }
  115.         if (crp) switch(crp->state)
  116.             {
  117. #if 1
  118.             case 'W':
  119.                 {
  120.                 int proc_no = 0;
  121.                 int cnt = sizeof(proc_tab)/sizeof(*proc_tab);
  122.                 while (--cnt && (!proc_tab[proc_no] || (proc_tab[proc_no]->parent != crp)))
  123.                     ++proc_no;
  124.                 if (!cnt)
  125.                     {
  126.                     crp->state = 'R';
  127.                     errno = ECHILD;
  128.                     crp->result = -1;
  129.                     }
  130.                 break;
  131.                 }
  132. #endif
  133.             case 'Z':
  134.                 {
  135.                 int arg = OPEN_MAX;
  136.                 while (arg--) if (crp->fd_tab[arg])
  137.                     {
  138.                     int stale = 1;
  139.                     int kfd = crp->fd_tab[arg];
  140.                     int cnt1 = sizeof(proc_tab)/sizeof(*proc_tab);
  141.                     crp->fd_tab[arg] = 0;
  142.                     while (cnt1--)
  143.                         {
  144.                         if (proc_tab[cnt1] && (proc_tab[cnt1]->state != 'Z'))
  145.                             {
  146.                             int cnt2 = OPEN_MAX;
  147.                             while (cnt2--)
  148.                                 {
  149.                                 if (proc_tab[cnt1]->fd_tab[cnt2] == kfd)
  150.                                     {
  151.     //                                kprintf("fd %d still open in proc %d\n", arg, proc_tab[cnt1]->pid);
  152.                                     stale = cnt1 = cnt2 = 0;
  153.                                     }
  154.                                 }
  155.                             }
  156.                         }
  157.                     if (stale) close(kfd);
  158.                     }
  159. #ifdef PROTECTED
  160.                 free_space(crp);
  161. #else
  162.                 if (!crp->sbreak)    /* must be relocatable */
  163.                     {
  164.                     struct mem_chain *storage = crp->storage;
  165.                     while (storage)
  166.                         {
  167.                         struct mem_chain *nxt = storage->nxt;
  168.                         DisposPtr((Ptr)storage);
  169.                         storage = nxt;
  170.                         }
  171.                     }
  172. #endif
  173.                 if (crp->savestack) free(crp->savestack);
  174.                 if (debug)
  175.                     kprintf("Activated pages = %ld\n", activated_pages);
  176.                 free(crp->p_sigacts);
  177.                 free(crp->self);
  178.     //            mstats("MMU");
  179.                 crp = proc_tab[proc_no] = 0;
  180.                     {
  181.                     ParamBlockRec    vol;
  182.                     vol.volumeParam.ioNamePtr = 0;
  183.                     vol.volumeParam.ioVRefNum = crt_ioVRefNum;
  184.                     PBFlushVolSync(&vol);
  185.                     }    
  186.                 break;
  187.                 }
  188.             case 'X':
  189.                 crp->state = 'Z';
  190.             case 'T':
  191.                 {
  192.                 if (crp->parent && (crp->parent->state=='W'))
  193.                     {
  194.                     crp->parent->state = 'D';
  195.                     crp->parent->registers.save[0] = SYS_wait4;
  196.                     }
  197.                 break;
  198.                 }
  199.             case 'D':
  200.                 {
  201.                 system_call();
  202.                 break;
  203.                 }
  204.             }
  205.         else checkevents();
  206.         old_ticks = now = get_ticks();
  207.         must_swap = 1;
  208.         }
  209.     while (!crp || crp->state != 'R');
  210.     }
  211.  
  212. struct args
  213.          {
  214.          void *dummy;
  215.          long arg1,arg2,arg3,arg4,arg5,arg6,arg7;
  216.          };
  217.  
  218. void system_call(void)
  219.     {
  220.      struct args s;
  221.      crp->state = 'R'; /* runnable unless otherwise overridden */
  222.      kumemcpy(crp, &s, crp->registers.save[15], sizeof(s));
  223. #ifdef SUN_COMPATIBLE
  224.      if ((unsigned long)s.dummy <= 183)
  225.          {
  226.          crp->registers.save[0] = (long)s.dummy;
  227.          memcpy(&s.arg1, &s.arg2, sizeof(s)-8);
  228.          crp->registers.save[15] += 4;
  229.          }
  230. #endif
  231.     crt_parID = crp->crt_parID;
  232.     root_parID = crp->root_parID;
  233.      if (debug) 
  234.          {
  235.          kprintf("System call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  236.          }
  237.      errno = ENOSYS;
  238.     switch(crp->registers.save[0])
  239.         {
  240.         default:
  241. #ifdef PROTECTED
  242.             if (virtual && !crp->registers.save[0])
  243.                 {
  244.                 crp->registers.pc = crp->header.a_entry;
  245.                 crp->registers.save[15] = crp->stack_limit-256;
  246.                 }
  247.             else
  248. #endif
  249.                 {
  250.                 kprintf("Unimplemented system call %s\n", callname(crp->registers.save[0]));
  251.                 crp->result = -1;
  252.                 }
  253.             break;
  254.         case SYS_exit:
  255.                 {
  256.                 crp->result = (s.arg1&255)<<8;
  257.                 crp->state = 'X';
  258.                 }
  259.             break;
  260.         case SYS_fork:
  261.             if (crp->sbreak)    /* genuine user mem proc. */
  262.                 {
  263.                 newproc(0, NULL, NULL, crp, 0, 0);
  264.                 crp->result = 0;
  265.                 /* save parent->result of system call */
  266.                     {
  267.                     enum {carry=1};
  268.                         {
  269.                         crp->parent->registers.save[0] = crp->pid;
  270.                         crp->parent->registers.flags &= ~carry;
  271.                         }
  272.                     crp->parent->registers.save[1] = 0;    /* is this correct ? */
  273.                     }
  274.                 break;
  275.                 }
  276.         case SYS_vfork:
  277.             {
  278.             newproc(0, NULL, NULL, crp, 0, 0);
  279.             crp->result = 0;
  280.             /* save parent->result of system call */
  281.                 {
  282.                 enum {carry=1};
  283.                     {
  284.                     crp->parent->registers.save[0] = crp->pid;
  285.                     crp->parent->registers.flags &= ~carry;
  286.                     }
  287.                 crp->parent->registers.save[1] = 0;    /* is this correct ? */
  288.                 }
  289.             break;
  290.             }
  291.         case SYS_read:
  292.             {
  293.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  294.             else
  295.                 {
  296.                 char *kbuf = xmalloc(s.arg3);
  297.                 int kfd = crp->fd_tab[s.arg1];
  298.                 if (kfd < 0) 
  299.                     crp->result = s_read(~kfd, kbuf, s.arg3);
  300.                 else
  301.                     crp->result = read(kfd, kbuf, s.arg3);
  302.                 ukmemcpy(crp, s.arg2, kbuf, crp->result);
  303.                 free(kbuf);
  304.                 if ((kfd >= 0) && (crt_fd_tab[kfd].flags & O_PIPE) && !crp->result)
  305.                     {
  306.                     int tot = (crt_fd_tab[kfd].fd&-256) == 100<<8;
  307.                     int cnt = sizeof(proc_tab)/sizeof(*proc_tab);
  308.                     while (cnt--)
  309.                         {
  310.                         if (proc_tab[cnt] && (proc_tab[cnt]->state != 'Z'))
  311.                             {
  312.                             int cnt2 = OPEN_MAX;
  313.                             while (cnt2--)
  314.                                 {
  315.                                 if (proc_tab[cnt]->fd_tab[cnt2] == kfd)
  316.                                     {
  317.                                     ++tot;
  318.                                     }
  319.                                 }
  320.                             }
  321.                         }
  322.                     if (tot > 1) crp->state = 'D';
  323.                     }
  324.                 }
  325.              if ((crp->result==-1))
  326.                  {
  327.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  328.                  }
  329.             break;
  330.             }
  331.         case SYS_write:
  332.             {
  333.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  334.             else
  335.                 {
  336.                 int kfd = crp->fd_tab[s.arg1];
  337.                 char *kbuf = xmalloc(s.arg3);
  338.                 kumemcpy(crp, kbuf, s.arg2, s.arg3);
  339.                 if (kfd < 0)
  340.                     crp->result = s_write(~kfd, kbuf, s.arg3);
  341.                 else
  342.                     crp->result = write(kfd, kbuf, s.arg3);
  343.                 free(kbuf);
  344.                 }
  345.              if ((crp->result==-1))
  346.                  {
  347.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  348.                  }
  349.             break;
  350.             }
  351.         case SYS_open:
  352.             {
  353.             int bufsiz = ustrlen(crp, s.arg1)+1;
  354.             char *kbuf = xmalloc(bufsiz);
  355.             kustrcpy(crp, (void *)kbuf, s.arg1);
  356.             if (debug) kprintf("Open %s\n", kbuf);    
  357.             crp->result = open(kbuf, s.arg2, s.arg3);
  358.             if (crp->result != -1)
  359.                 {
  360.                 int fd = 0;
  361.                 while ((fd <= OPEN_MAX) && crp->fd_tab[fd]) ++fd;
  362.                 if (fd <= OPEN_MAX) 
  363.                     {
  364.                     crp->fd_tab[fd] = crp->result;
  365.                     crp->result = fd;
  366.                     }
  367.                 else
  368.                     {
  369.                     close(crp->result);
  370.                     crp->result = -1;
  371.                     }
  372.                 }    
  373.             free((void *)kbuf);
  374.             break;
  375.             }
  376.         case SYS_close:
  377.             crp->result = -1;
  378.             if ((s.arg1>=0)&&(s.arg1<=OPEN_MAX)&&crp->fd_tab[s.arg1])
  379.                 {
  380.                 int kfd = crp->fd_tab[s.arg1];
  381.                 int cnt = sizeof(proc_tab)/sizeof(*proc_tab);
  382.                 crp->fd_tab[s.arg1] = 0;
  383.                 while (cnt--)
  384.                     {
  385.                     if (proc_tab[cnt] && (proc_tab[cnt]->state != 'Z'))
  386.                         {
  387.                         int cnt2 = OPEN_MAX;
  388.                         while (cnt2--)
  389.                             {
  390.                             if (proc_tab[cnt]->fd_tab[cnt2] == kfd)
  391.                                 {
  392. //                                kprintf("fd %d still open in proc %d\n", s.arg1, proc_tab[cnt]->pid);
  393.                                 crp->result = cnt = cnt2 = 0;
  394.                                 }
  395.                             }
  396.                         }
  397.                     }
  398.                 if (crp->result)
  399.                     {
  400.                     if (kfd < 0)
  401.                         crp->result = s_close(~kfd);
  402.                     else
  403.                         crp->result = close(kfd);
  404.                     }
  405.                 }
  406.             break;
  407.         case SYS_wait4:
  408.             {
  409.             int proc_no = 0;
  410.             int cnt = sizeof(proc_tab)/sizeof(*proc_tab);
  411.             while (--cnt && (!proc_tab[proc_no] || (proc_tab[proc_no]->parent != crp) 
  412.                 || ((s.arg1 != -1) && (s.arg1 != proc_tab[proc_no]->pid))))
  413.                 ++proc_no;
  414.             if (cnt)
  415.                 {
  416.                 if ((proc_tab[proc_no]->state == 'T') || (proc_tab[proc_no]->state == 'Z'))
  417.                         {
  418.                         int waitcode = proc_tab[proc_no]->result;
  419.                         ukmemcpy(crp, s.arg2, &waitcode, sizeof(int)); /* for retcode */
  420.                         crp->result = proc_tab[proc_no]->pid;
  421.                         errno = 0;
  422.                         }
  423.                 else
  424.                         {
  425.                         crp->state = 'W';
  426.                         crp->result = s.arg2;
  427.                         }
  428.                 }
  429.             else    
  430.                 {
  431.                 errno = ECHILD;
  432.                 umemset(crp, s.arg2, 0, sizeof(int));
  433.                 crp->result = -1;
  434.                 }
  435.             break;
  436.             }
  437.         case SYS_link:
  438.             errno = EMLINK;
  439.             crp->result = -1;
  440.             break;
  441.         case SYS_unlink:
  442.             {
  443.             int bufsiz = ustrlen(crp, s.arg1)+1;
  444.             char *kbuf = xmalloc(bufsiz);
  445.             kustrcpy(crp, kbuf, s.arg1);            
  446.             crp->result = unlink(kbuf);
  447.             free(kbuf);
  448.             break;
  449.             }
  450.         case SYS_chdir:
  451.             {
  452.             int bufsiz = ustrlen(crp, s.arg1)+1;
  453.             char *kbuf = xmalloc(bufsiz);
  454.             kustrcpy(crp, kbuf, s.arg1);            
  455.             crp->result = chdir(kbuf);
  456.             if (!crp->result) crp->crt_parID = crt_parID;
  457.             free(kbuf);
  458.             break;
  459.             }
  460.         case SYS_fchdir:
  461.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  462.             else crp->result = fchdir(crp->fd_tab[s.arg1]);
  463.             if (!crp->result) crp->crt_parID = crt_parID;
  464.             break;
  465.         case SYS_mknod:
  466.             {
  467.             int bufsiz = ustrlen(crp, s.arg1)+1;
  468.             char *kbuf = xmalloc(bufsiz);
  469.             kustrcpy(crp, kbuf, s.arg1);            
  470.             crp->result = mknod(kbuf, s.arg2, s.arg3);
  471.             free(kbuf);
  472.             break;
  473.             }            
  474.         case SYS_chmod:
  475.             {
  476.             int bufsiz = ustrlen(crp, s.arg1)+1;
  477.             char *kbuf = xmalloc(bufsiz);
  478.             kustrcpy(crp, kbuf, s.arg1);            
  479.             crp->result = chmod(kbuf, s.arg2);
  480.             free(kbuf);
  481.             break;
  482.             }
  483.         case SYS_chown:
  484.             {
  485.             int bufsiz = ustrlen(crp, s.arg1)+1;
  486.             char *kbuf = xmalloc(bufsiz);
  487.             kustrcpy(crp, kbuf, s.arg1);            
  488.             crp->result = chown(kbuf, s.arg2, s.arg3);
  489.             free(kbuf);
  490.             break;
  491.             }
  492.         case SYS_lseek:
  493.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  494.             else crp->result = lseek(crp->fd_tab[s.arg1], s.arg2, s.arg3);
  495.             break;
  496.         case SYS_getpid:
  497.             crp->result = crp->pid;
  498.             break;
  499.         case SYS_getuid:
  500.             crp->result = 0;
  501.             break;
  502.         case SYS_geteuid:
  503.             crp->result = 0;
  504.             break;
  505.         case SYS_ptrace:
  506.             {
  507.             struct mmu *child = NULL;
  508.             int pid = s.arg2;
  509.             long addr = s.arg3;
  510.             long data = s.arg4;
  511.             int proc_no = 0;
  512.             int cnt = sizeof(proc_tab)/sizeof(*proc_tab);
  513.             while (--cnt && (!proc_tab[proc_no] || (pid != proc_tab[proc_no]->pid)))
  514.                 ++proc_no;
  515.             if (cnt)
  516.                 {
  517.                 child = proc_tab[proc_no];
  518.                 if ((child->state != 'T') || !child->trace_me)
  519.                     {
  520.                     errno = ECHILD;
  521.                     break;
  522.                     }
  523.                 else crp->result = 0;
  524.                 }
  525.             else    
  526.                 errno = ECHILD;
  527.             if (debug) kprintf("ptrace(%d,%d,%08X,%08X)\n", s.arg1, pid, addr, data);
  528.             switch(s.arg1)
  529.                 {
  530.                 case     PT_TRACE_ME    : if (debug) kprintf("child declares it's being traced\n");
  531.                     crp->trace_me = 1; 
  532.                     crp->result = 0;
  533.                     break;
  534.                 case     PT_READ_I    :
  535.                 case     PT_READ_D    : if (debug) kprintf("read word in child's I/D space\n"); 
  536.                     if (child)
  537.                         kumemcpy(child, &(crp->result), addr, sizeof(long));                    
  538.                     break;
  539.                 case     PT_READ_U    : kprintf("read word in child's user structure\n"); 
  540.                     crp->result = -1;
  541.                     break;
  542.                 case     PT_WRITE_I    :
  543.                 case     PT_WRITE_D    : if (debug) kprintf("write word in child's I/D space\n"); 
  544.                     if (child)
  545.                         ukmemcpy(child, addr, &data, sizeof(long));
  546.                     break;
  547.                 case     PT_WRITE_U    : kprintf("write word in child's user structure\n"); 
  548.                     crp->result = -1;
  549.                     break;
  550.                 case     PT_CONTINUE    : if (debug) kprintf("continue the child\n"); 
  551.                     {
  552.                     if (child) 
  553.                         child->state = 'R';
  554.                     break;
  555.                     }
  556.                 case     PT_KILL        : if (debug) kprintf("kill the child process\n"); 
  557.                     if (child) 
  558.                         child->state = 'Z';
  559.                     break;
  560.                 case     PT_STEP        : if (debug) kprintf("single step the child\n"); 
  561.                     if (child)
  562.                         {
  563.                         child->registers.flags |= 0x8000;
  564.                         child->state = 'R';
  565.                         }
  566.                     break;
  567.                 case     PT_ATTACH    : kprintf("attach to running process\n"); 
  568.                     crp->result = -1;
  569.                     break;
  570.                 case     PT_DETACH    : kprintf("detach from running process\n");
  571.                     crp->result = -1;
  572.                     break;
  573.                 case     PT_GETREGS    : if (debug) kprintf("fetch registers\n");
  574.                     if (child)
  575.                         ukmemcpy(crp, addr, &(child->registers), sizeof(struct userregs));
  576.                     break;
  577.                 case     PT_SETREGS    : if (debug) kprintf("set registers\n"); 
  578.                     if (child)
  579.                         kumemcpy(crp, &(child->registers), addr, sizeof(struct userregs));
  580.                     break;
  581.                 default : crp->result = -1;
  582.                 }
  583.             break;
  584.             }
  585. #if 0
  586.         case SYS_recvmsg:
  587.         case SYS_sendmsg:
  588. #endif
  589.         case SYS_recvfrom:
  590.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  591.             else
  592.                 {
  593.                 int kfd = crp->fd_tab[s.arg1];
  594.                 if (kfd < 0) 
  595.                     {
  596.                     int fromlen;
  597.                     struct sockaddr sa_from;
  598.                     char *buffer = xmalloc(s.arg3);
  599.                     kumemcpy(crp, &sa_from, s.arg5, sizeof(sa_from));
  600.                     crp->result = s_sendto (~kfd, buffer, s.arg3, s.arg4, &sa_from, &fromlen);
  601.                     ukmemcpy(crp, s.arg5, &sa_from, sizeof(sa_from));
  602.                     ukmemcpy(crp, s.arg2, buffer, fromlen);
  603.                     ukmemcpy(crp, s.arg6, &fromlen, sizeof(int));
  604.                     free(buffer);
  605.                     }
  606.                 }
  607.              if ((crp->result==-1))
  608.                  {
  609.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  610.                  }
  611.             break;
  612.         case SYS_accept:
  613.             {
  614.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  615.             else
  616.                 {
  617.                 int kfd = crp->fd_tab[s.arg1];
  618.                 if (kfd < 0) 
  619.                     {
  620.                     int addrlen;
  621.                     struct sockaddr sa_addr;
  622.                     kumemcpy(crp, &sa_addr, s.arg2, sizeof(sa_addr));
  623.                     kumemcpy(crp, &addrlen, s.arg3, sizeof(long));
  624.                     crp->result = s_accept(~kfd, &sa_addr, &addrlen);
  625.                     ukmemcpy(crp, s.arg2, &sa_addr, sizeof(sa_addr));
  626.                     ukmemcpy(crp, s.arg3, &addrlen, sizeof(long));
  627.                     }
  628.                 }
  629.              if ((crp->result==-1))
  630.                  {
  631.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  632.                  }
  633.             break;
  634.             }
  635. #if 0
  636.         case SYS_getpeername:
  637.         case SYS_getsockname:
  638.             break;
  639. #endif
  640.         case SYS_symlink:
  641.             {
  642.             int bufsiz1 = ustrlen(crp, s.arg1)+1;
  643.             char *kbuf1 = xmalloc(bufsiz1);
  644.             int bufsiz2 = ustrlen(crp, s.arg2)+1;
  645.             char *kbuf2 = xmalloc(bufsiz2);
  646.             kustrcpy(crp, kbuf1, s.arg1);            
  647.             kustrcpy(crp, kbuf2, s.arg2);            
  648.             crp->result = symlink(kbuf1, kbuf2);
  649.             free(kbuf1);
  650.             free(kbuf2);
  651.             break;
  652.             }
  653.         case SYS_readlink:
  654.             {
  655.             int bufsiz1 = ustrlen(crp, s.arg1)+1;
  656.             char *kbuf1 = xmalloc(bufsiz1);
  657.             char *kbuf2 = xmalloc(s.arg3);
  658.             kustrcpy(crp, kbuf1, s.arg1);            
  659.             crp->result = readlink(kbuf1, kbuf2, s.arg3);
  660.             ukmemcpy(crp, s.arg2, kbuf2, crp->result+1);
  661.             free(kbuf1);
  662.             free(kbuf2);
  663.             break;
  664.             }
  665.         case SYS_execve:
  666.             {
  667.             extern short nxt_pid;
  668.             int proc;
  669.             int bufsiz = ustrlen(crp, s.arg1)+1;
  670.             struct mmu *parent = crp->parent;
  671.             struct mmu *predecessor = crp;
  672.             char *kbuf = xmalloc(bufsiz);
  673.             enum    {maxargs=2048,maxenv=2048};
  674.             char **argp = (char **)s.arg2;
  675.             char **env = (char **)s.arg3;
  676.             char *ptr;
  677.             char **args = (char **)xmalloc(maxargs*sizeof(char *));
  678.             char **envs = (char **)xmalloc(maxenv*sizeof(char *));
  679.             long argcnt = 0;
  680.             long envcnt = 0;
  681.             do
  682.                 {
  683.                 kumemcpy(parent, &ptr, (long)argp, sizeof(char *));
  684.                 if (ptr)
  685.                     {
  686.                     long bufsiz = ustrlen(parent, (long)ptr)+1;
  687.                     char *kbuf = xmalloc(bufsiz);
  688.                     kustrcpy(parent, kbuf, (long)ptr);
  689.                     args[argcnt] = kbuf;
  690.                     ++argcnt;
  691.                     ++argp;
  692.                     }
  693.                 }
  694.             while (ptr && (argcnt<maxargs));
  695.             do
  696.                 {
  697.                 kumemcpy(parent, &ptr, (long)env, sizeof(char *));
  698.                 if (ptr)
  699.                     {
  700.                     long bufsiz = ustrlen(parent, (long)ptr)+1;
  701.                     char *kbuf = xmalloc(bufsiz);
  702.                     kustrcpy(parent, kbuf, (long)ptr);
  703.                     envs[envcnt] = kbuf;
  704.                     ++envcnt;
  705.                     ++env;
  706.                     }
  707.                 }
  708.             while (ptr && (envcnt<maxenv));
  709.             kustrcpy(crp, kbuf, s.arg1);
  710.             --nxt_pid;
  711.             crp->result = newproc(kbuf, args, envs, crp, argcnt, envcnt);
  712.             free(envs);
  713.             free(args);
  714.             crp->parent = parent;
  715.             free(kbuf);
  716. #if 0
  717.             if (debug)
  718.                 {
  719.                 char debugstr[99];
  720.                 long phys_pc = (long)LTP(crp->registers.pc);
  721.                 ksprintf(debugstr+1, "PC kernel address = %8.8X\n", phys_pc);
  722.                 *debugstr = strlen(debugstr+1);
  723.                 kprintf(debugstr+1);
  724.                 DebugStr(debugstr);
  725.                 }
  726. #endif
  727.             if (crp->trace_me)
  728.                 {
  729.                 crp->state = 'T';
  730.                 crp->result = W_STOPCODE(SIGTRAP);
  731.                 }
  732. #if 0
  733.             if (predecessor->savestack)    /* saved from vfork() */
  734.                 {
  735.                 enum {carry = 1};
  736.                 predecessor->result = crp->pid;
  737.                 predecessor->registers = predecessor->saveregs;
  738.                 ukmemcpy(predecessor, predecessor->registers.save[15], predecessor->savestack, predecessor->stack_limit - predecessor->registers.save[15]);
  739.                 free(predecessor->savestack);
  740.                 predecessor->savestack = 0;
  741.                 predecessor->registers.save[0] = crp->pid;
  742.                 predecessor->registers.flags &= ~carry;
  743.                 predecessor->state = 'W';
  744.                 crp->parent = predecessor;
  745.                 }
  746. #endif
  747.             break;
  748.             }
  749.         case SYS_umask:
  750.             crp->result = 0;
  751.             break;
  752.         case SYS_fstat:
  753.             {
  754.             struct stat kstat;
  755.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  756.             else crp->result = fstat(crp->fd_tab[s.arg1], &kstat);
  757.             ukmemcpy(crp, s.arg2, &kstat, sizeof(struct stat));
  758.             break;
  759.             }
  760.         case SYS_access:
  761.             {
  762.             int bufsiz = ustrlen(crp, s.arg1)+1;
  763.             char *kbuf = xmalloc(bufsiz);
  764.             kustrcpy(crp, kbuf, s.arg1);            
  765.             crp->result = access(kbuf, s.arg2);
  766.             free(kbuf);
  767.             break;
  768.             }
  769.         case SYS_kill:
  770.             crp->result = 0;
  771.             break;
  772.         case SYS_stat:
  773.             {
  774.             int bufsiz = ustrlen(crp, s.arg1)+1;
  775.             struct stat kstat;
  776.             char *kbuf = xmalloc(bufsiz);
  777.             kustrcpy(crp, kbuf, s.arg1);            
  778.             crp->result = stat(kbuf, &kstat);
  779.             ukmemcpy(crp, s.arg2, &kstat, sizeof(struct stat));
  780.             free(kbuf);
  781.             break;
  782.             }
  783.         case SYS_lstat:
  784.             {
  785.             int bufsiz = ustrlen(crp, s.arg1)+1;
  786.             struct stat kstat;
  787.             char *kbuf = xmalloc(bufsiz);
  788.             kustrcpy(crp, kbuf, s.arg1);            
  789.             crp->result = lstat(kbuf, &kstat);
  790.             ukmemcpy(crp, s.arg2, &kstat, sizeof(struct stat));
  791.             free(kbuf);
  792.             break;
  793.             }
  794.         case SYS_getppid:
  795.             crp->result = 1;
  796.             break;
  797.         case SYS_dup:
  798.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  799.             else
  800.                 {
  801.                 int fd = 0;
  802.                 while ((fd <= OPEN_MAX) && crp->fd_tab[fd]) ++fd;
  803.                 if (fd <= OPEN_MAX) 
  804.                     {
  805.                     crp->fd_tab[fd] = s.arg1;
  806.                     crp->result = fd;
  807.                     }
  808.                 else
  809.                     {
  810.                     crp->result = -1;
  811.                     }
  812.                 }    
  813.             break;
  814.         case SYS_pipe:
  815.             {
  816.             int arg[2],i;
  817.             crp->result = pipe(arg);
  818.             if (!crp->result) for (i= 0; i < 2; i++)
  819.                 {
  820.                 int fd = 0;
  821.                 while ((fd <= OPEN_MAX) && crp->fd_tab[fd]) ++fd;
  822.                 if (fd <= OPEN_MAX) 
  823.                     {
  824.                     crp->fd_tab[fd] = arg[1];
  825.                     arg[i] = fd;
  826.                     }
  827.                 else
  828.                     {
  829.                     crp->result = -1;
  830.                     }
  831.                 }    
  832.             ukmemcpy(crp, s.arg1, arg, sizeof(arg));
  833.             if (debug) kprintf("pipe(%x[]={%x,%x}) returned %d\n", s.arg1, arg[0], arg[1], crp->result);
  834.             break;
  835.             }
  836.         case SYS_getegid:
  837.             crp->result = 0;
  838.             break;
  839.         case SYS_sigaction:
  840.             {
  841.             struct sigaction tmp_sig;
  842.             kumemcpy(crp, &tmp_sig, s.arg2, sizeof(struct sigaction));
  843.             crp->result = sigaction(s.arg1, &tmp_sig, &tmp_sig);
  844.             ukmemcpy(crp, s.arg3, &tmp_sig, sizeof(struct sigaction));
  845.             break;
  846.             }
  847.         case SYS_getgid:
  848.             crp->result = 0;
  849.             break;
  850.         case SYS_sigprocmask:
  851.             {
  852.             sigset_t mask1,mask2;
  853.             kumemcpy(crp, &mask1, s.arg2, sizeof(sigset_t));
  854.             kumemcpy(crp, &mask2, s.arg3, sizeof(sigset_t));
  855.             crp->result = sigprocmask(s.arg1, &mask1, &mask2);
  856.             ukmemcpy(crp, s.arg3, &mask2, sizeof(sigset_t));
  857.             break;
  858.             }
  859.         case SYS_getlogin:
  860.             crp->result = 0;
  861.             break;
  862.         case SYS_setlogin:
  863.             crp->result = -1;
  864.             break;
  865.         case SYS_ioctl:
  866.             {
  867.             void *kbuf = xmalloc(IOCPARM_LEN(s.arg2));
  868.             kumemcpy(crp, kbuf, s.arg3, IOCPARM_LEN(s.arg2));
  869.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  870.             else crp->result = ioctl(crp->fd_tab[s.arg1], s.arg2, kbuf);
  871.             ukmemcpy(crp, s.arg3, kbuf, IOCPARM_LEN(s.arg2));
  872.             free(kbuf);
  873.             break;
  874.             }
  875.         case SYS_getpagesize:
  876.             crp->result = page_size;
  877.             break;
  878.         case SYS_sbrk:
  879.             s.arg1 += crp->sbreak;
  880.             if (!crp->sbreak)    /* supervisor address space relocatable process */
  881.                 {
  882.                 Ptr nxt = NewPtrClear(s.arg1+sizeof(void *));
  883.                 if (!nxt) crp->result = -1;
  884.                 else
  885.                     {
  886.                     struct mem_chain *last = crp->storage;
  887.                     crp->storage = (struct mem_chain *)nxt;
  888.                     crp->storage->nxt = last;
  889.                     crp->result = (long)(crp->storage->storage);
  890. #ifdef PROTECTED
  891.                       supervisor_space(crp, crp->result, crp->result+s.arg1);
  892. #endif
  893.                     }
  894.                 break;
  895.                 }
  896. #ifdef PROTECTED
  897.         case SYS_break:
  898.             if (!crp->sbreak || (s.arg1 > crp->registers.save[15]-8192)) crp->result = -1;
  899.             else
  900.                 {
  901.                 if (s.arg1 > crp->sbreak)
  902.                     {
  903.                     long siz = s.arg1 - crp->sbreak;
  904.                     if (lower_space(crp, s.arg1))
  905.                         crp->result = -1;
  906.                     else 
  907.                         {
  908.                         crp->result = crp->sbreak;
  909.                         crp->sbreak = s.arg1;
  910.                         umemset(crp, crp->result, 0, siz);
  911.                         }
  912.                     }
  913.                 }
  914.             break;
  915.         case SYS_mmap:
  916. //            crp->result = (long)mmap((caddr_t)s.arg1,s.arg2,s.arg3,s.arg4,s.arg5,s.arg6);
  917.             break;
  918.         case SYS_munmap:
  919. //            crp->result = (long)munmap((caddr_t)s.arg1,s.arg2,s.arg3,s.arg4,s.arg5,s.arg6);
  920.             crp->result = 0; /* just pretend to succeed */
  921.             break;
  922. #endif
  923.         case SYS_getgroups:
  924.             {
  925.             int *groups = xmalloc(s.arg1*sizeof(int));
  926.             crp->result = getgroups(s.arg1, groups);
  927.             ukmemcpy(crp, s.arg2, groups, s.arg1*sizeof(int));
  928.             free(groups);
  929.             break;
  930.             }
  931.         case SYS_getpgrp:
  932.             crp->result = 12345;
  933.             break;
  934.         case SYS_setpgid:
  935.             crp->result = 0;
  936.             break;
  937.         case SYS_getdtablesize:
  938.             crp->result = getdtablesize();
  939.             break;
  940.         case SYS_gethostname:
  941.             {
  942.             char *machname = xmalloc(s.arg2);
  943.             crp->result = gethostname( machname, s.arg2);
  944.             ukmemcpy(crp, s.arg1, machname, s.arg2);
  945.             free(machname);
  946.             break;
  947.             }
  948.         case SYS_dup2:
  949.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  950.             else
  951.                 {
  952.                 crp->fd_tab[s.arg2] = crp->fd_tab[s.arg1];
  953.                 crp->result = 0;
  954.                 }
  955.             break;
  956.         case SYS_fcntl:
  957.             if (debug) kprintf("fcntl(%d,%d,%d)\n", s.arg1, s.arg2, s.arg3);
  958.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  959.             else switch(s.arg2)
  960.                  {
  961.                  case F_DUPFD :
  962.                     {
  963.                     int fd = s.arg3;
  964.                     while ((fd <= OPEN_MAX) && crp->fd_tab[fd]) ++fd;
  965.                     if (fd <= OPEN_MAX) 
  966.                         {
  967.                         crp->fd_tab[fd] = crp->fd_tab[s.arg1];
  968.                         crp->result = fd;
  969.                         }
  970.                     else
  971.                         {
  972.                         crp->result = -1;
  973.                         }
  974.                      break;
  975.                      }
  976.                  case F_SETFD : 
  977.                      if (debug) kprintf("Set fd flags\n"); 
  978.                      crp->result = 0; break;
  979.                 case F_GETFL : 
  980.                     if (debug) kprintf("Get file status flags\n"); 
  981.                     crp->result = O_RDWR; break; /* dummy */
  982.                 case F_SETFL : 
  983.                     if (debug) kprintf("Set file status flags\n"); 
  984.                     crp->result = 0; break;
  985.                  default: kprintf("Unsupported fcntl cmd %d\n", s.arg2);
  986.                  }
  987.             break;
  988.         case SYS_select:
  989.             {
  990.             long tab,width,max = 0;
  991.             fd_set fds[3],kfds[3];
  992.             struct timeval timeout;
  993.             if (s.arg2) kumemcpy(crp, &fds[0], s.arg2, sizeof(fd_set));
  994.             else FD_ZERO(&fds[0]);
  995.             if (s.arg3) kumemcpy(crp, &fds[1], s.arg3, sizeof(fd_set));
  996.             else FD_ZERO(&fds[1]);
  997.             if (s.arg4) kumemcpy(crp, &fds[2], s.arg4, sizeof(fd_set));
  998.             else FD_ZERO(&fds[2]);
  999.             kumemcpy(crp, &timeout, s.arg5, sizeof(timeout));
  1000.             for (tab = 3; tab--; )
  1001.                 {
  1002.                 FD_ZERO(&kfds[tab]);
  1003.                 for (width = s.arg1; width--; )
  1004.                     {
  1005.                     if (FD_ISSET(width, &fds[tab]) && crp->fd_tab[width])
  1006.                         {
  1007.                         int kfd = crp->fd_tab[width];
  1008.                         if (kfd < 0)
  1009.                             {
  1010.                             if (~kfd > max) max = ~kfd;
  1011.                             FD_SET(~kfd, &kfds[tab]);
  1012.                             }
  1013.                         }
  1014.                     }
  1015.                 }
  1016.             crp->result = s_select(max+1, &kfds[0], &kfds[1], &kfds[2], &timeout);
  1017.             if (crp->result != -1) for (tab = 3; tab--; )
  1018.                 {
  1019.                 for (width = s.arg1; width--; ) if (FD_ISSET(width, &fds[tab]))
  1020.                     {
  1021.                     if (crp->fd_tab[width])
  1022.                         {
  1023.                         int kfd = crp->fd_tab[width];
  1024.                         if (kfd < 0)
  1025.                             {
  1026.                             if (!FD_ISSET(~kfd, &kfds[tab]))
  1027.                                 {
  1028.                                 FD_CLR(width, &fds[tab]);
  1029.                                 kprintf("Nothing available chan %d fd %d (%d)\n", tab, width, ~kfd);
  1030.                                 }
  1031.                             else kprintf("Data available chan %d fd %d (%d)\n", tab, width, ~kfd);
  1032.                             }
  1033.                         else
  1034.                             {
  1035.                             FD_CLR(width, &fds[tab]);
  1036.                             kprintf("Select on a non-socket\n");
  1037.                             }
  1038.                         }
  1039.                     else
  1040.                         {
  1041.                         FD_CLR(width, &fds[tab]);
  1042.                         kprintf("Select on a closed fd %d\n", width);
  1043.                         }
  1044.                     }
  1045.                 }
  1046.             if (s.arg2) ukmemcpy(crp, s.arg2, &fds[0], sizeof(fd_set));
  1047.             if (s.arg3) ukmemcpy(crp, s.arg3, &fds[1], sizeof(fd_set));
  1048.             if (s.arg4) ukmemcpy(crp, s.arg4, &fds[2], sizeof(fd_set));
  1049.             break;
  1050.             }
  1051.         case SYS_socket:
  1052.             crp->result = s_socket(s.arg1, s.arg2, s.arg3);
  1053.             if (crp->result != -1)
  1054.                 {
  1055.                 int fd = 0;
  1056.                 while ((fd <= OPEN_MAX) && crp->fd_tab[fd]) ++fd;
  1057.                 if (fd <= OPEN_MAX) 
  1058.                     {
  1059.                     crp->fd_tab[fd] = ~crp->result;
  1060.                     crp->result = fd;
  1061.                     }
  1062.                 else
  1063.                     {
  1064.                     s_close(crp->result);
  1065.                     crp->result = -1;
  1066.                     }
  1067.                 }    
  1068.              if ((crp->result==-1))
  1069.                  {
  1070.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  1071.                  }
  1072.             break;
  1073.         case SYS_connect:
  1074.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  1075.             else
  1076.                 {
  1077.                 int kfd = crp->fd_tab[s.arg1];
  1078.                 if (kfd < 0) 
  1079.                     {
  1080.                     struct sockaddr sa_addr;
  1081.                     kumemcpy(crp, &sa_addr, s.arg2, sizeof(sa_addr));
  1082.                     crp->result = s_connect(~kfd, &sa_addr, s.arg3);
  1083.                     ukmemcpy(crp, s.arg2, &sa_addr, sizeof(sa_addr));
  1084.                     }
  1085.                 }
  1086.              if ((crp->result==-1))
  1087.                  {
  1088.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  1089.                  }
  1090.             break;
  1091.         case SYS_getpriority:
  1092.             crp->result = 0;
  1093.             break;
  1094.         case SYS_sigreturn:
  1095.             {
  1096.             struct sigcontext context;
  1097.             kumemcpy(crp, &context, s.arg1, sizeof(struct sigcontext));
  1098.             crp->result = sigreturn(&context);
  1099.             ukmemcpy(crp, s.arg1, &context, sizeof(struct sigcontext));
  1100.             break;
  1101.             }
  1102.         case SYS_bind:
  1103.             {
  1104.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  1105.             else
  1106.                 {
  1107.                 int kfd = crp->fd_tab[s.arg1];
  1108.                 if (kfd < 0) 
  1109.                     {
  1110.                     struct sockaddr sa_addr;
  1111.                     kumemcpy(crp, &sa_addr, s.arg2, sizeof(sa_addr));
  1112.                     crp->result = s_bind(~kfd, &sa_addr, s.arg3);
  1113.                     ukmemcpy(crp, s.arg2, &sa_addr, sizeof(sa_addr));
  1114.                     }
  1115.                 }
  1116.              if ((crp->result==-1))
  1117.                  {
  1118.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  1119.                  }
  1120.             break;
  1121.             }
  1122.         case SYS_setsockopt:
  1123.             errno = EOPNOTSUPP;
  1124.             crp->result = -1;
  1125.             break;
  1126.         case SYS_listen:
  1127.             {
  1128.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  1129.             else
  1130.                 {
  1131.                 int kfd = crp->fd_tab[s.arg1];
  1132.                 if (kfd < 0) 
  1133.                     {
  1134.                     crp->result = s_listen(~kfd, s.arg2);
  1135.                     }
  1136.                 }
  1137.              if ((crp->result==-1))
  1138.                  {
  1139.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  1140.                  }
  1141.             break;
  1142.             }
  1143.         case SYS_sigstack:
  1144.             {
  1145.             struct sigstack stack1,stack2;
  1146.             kumemcpy(crp, &stack1, s.arg1, sizeof(struct sigstack));
  1147.             kumemcpy(crp, &stack2, s.arg2, sizeof(struct sigstack));
  1148.             crp->result = sigstack(&stack1, &stack2);
  1149.             ukmemcpy(crp, s.arg2, &stack2, sizeof(struct sigstack));
  1150.             break;
  1151.             }
  1152.         case SYS_sigsuspend:
  1153.             {
  1154.             sigset_t mask1;
  1155.             kumemcpy(crp, &mask1, s.arg1, sizeof(sigset_t));
  1156.             crp->result = sigsuspend(&mask1);
  1157.             crp->state = 'W';
  1158.             break;
  1159.             }
  1160.         case SYS_gettimeofday:
  1161.             {
  1162.             struct timeval ktime;
  1163.             struct timezone kzone;
  1164.             memset(&kzone, 0, sizeof(kzone));
  1165.             ktime.tv_sec = unixTime(get_time());
  1166.             ktime.tv_usec = (get_ticks()%60)*1000000/60;
  1167.             if (s.arg1) ukmemcpy(crp, s.arg1, &ktime, sizeof(ktime));
  1168.             if (s.arg2) ukmemcpy(crp, s.arg2, &kzone, sizeof(kzone));
  1169.             crp->result = 0;
  1170.             break;
  1171.             }
  1172.         case SYS_getsockopt:
  1173.             errno = EOPNOTSUPP;
  1174.             crp->result = -1;
  1175.             break;
  1176.         case SYS_getrusage:
  1177.             {
  1178.             struct rusage kusage;
  1179.             memset(&kusage, 0, sizeof(kusage));
  1180.             crp->result = 0;
  1181.             kusage.ru_utime.tv_usec = (crp->ticks%60)*1000000L/60;
  1182.             kusage.ru_utime.tv_sec = crp->ticks/60;
  1183.             ukmemcpy(crp, s.arg2, &kusage, sizeof(kusage));
  1184.             break;
  1185.             }
  1186.         case SYS_writev:
  1187.             {
  1188.             int i;
  1189.             struct iovec *iov = xmalloc(s.arg3*sizeof(struct iovec));
  1190.             kumemcpy(crp, iov, s.arg2, s.arg3*sizeof(struct iovec));
  1191.             crp->result = 0;
  1192.             for (i = 0; i < s.arg3; i++)        
  1193.                 {
  1194.                 char *kbuf = xmalloc(iov[i].iov_len);
  1195.                 kumemcpy(crp, kbuf, (long)iov[i].iov_base, iov[i].iov_len);
  1196.                 if ((crp->result==-1)||(s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1])
  1197.                     {
  1198.                     i = s.arg3;
  1199.                     crp->result = -1;
  1200.                     }
  1201.                 else crp->result = write(crp->fd_tab[s.arg1], kbuf, iov[i].iov_len);
  1202.                 free(kbuf);
  1203.                 }
  1204.             free(iov);
  1205.             break;
  1206.             }
  1207.         case SYS_rename:
  1208.             {
  1209.             int bufsiz1 = ustrlen(crp, s.arg1)+1;
  1210.             char *kbuf1 = xmalloc(bufsiz1);
  1211.             int bufsiz2 = ustrlen(crp, s.arg2)+1;
  1212.             char *kbuf2 = xmalloc(bufsiz2);
  1213.             kustrcpy(crp, kbuf1, s.arg1);            
  1214.             kustrcpy(crp, kbuf2, s.arg2);            
  1215.             crp->result = rename(kbuf1, kbuf2);
  1216.             free(kbuf1);
  1217.             free(kbuf2);
  1218.             break;
  1219.             }
  1220.         case SYS_ftruncate:
  1221.             {
  1222.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  1223.             else crp->result = ftruncate(crp->fd_tab[s.arg1], s.arg2);
  1224.             break;
  1225.             }
  1226.         case SYS_sendto:
  1227.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  1228.             else
  1229.                 {
  1230.                 int kfd = crp->fd_tab[s.arg1];
  1231.                 if (kfd < 0) 
  1232.                     {
  1233.                     int tolen;
  1234.                     struct sockaddr sa_to;
  1235.                     char *buffer = xmalloc(s.arg3);
  1236.                     kumemcpy(crp, buffer, s.arg2, s.arg3);
  1237.                     kumemcpy(crp, &sa_to, s.arg5, sizeof(sa_to));
  1238.                     crp->result = s_sendto (~kfd, buffer, s.arg3, s.arg4, &sa_to, &tolen);
  1239.                     ukmemcpy(crp, s.arg5, &sa_to, sizeof(sa_to));
  1240.                     ukmemcpy(crp, s.arg6, &tolen, sizeof(int));
  1241.                     free(buffer);
  1242.                     }
  1243.                 }
  1244.              if ((crp->result==-1))
  1245.                  {
  1246.                  kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  1247.                  }
  1248.             break;
  1249.         case SYS_mkdir:
  1250.             {
  1251.             int bufsiz = ustrlen(crp, s.arg1)+1;
  1252.             char *kbuf = xmalloc(bufsiz);
  1253.             kustrcpy(crp, kbuf, s.arg1);            
  1254.             crp->result = mkdir(kbuf, s.arg2);
  1255.             free(kbuf);        
  1256.             break;
  1257.             }
  1258.         case SYS_rmdir:
  1259.             {
  1260.             int bufsiz = ustrlen(crp, s.arg1)+1;
  1261.             char *kbuf = xmalloc(bufsiz);
  1262.             kustrcpy(crp, kbuf, s.arg1);            
  1263.             crp->result = rmdir(kbuf);    
  1264.             free(kbuf);        
  1265.             break;
  1266.             }
  1267.         case SYS_utimes:
  1268.             {
  1269.             struct timeval temps;
  1270.             int bufsiz = ustrlen(crp, s.arg1)+1;
  1271.             char *kbuf = xmalloc(bufsiz);
  1272.             kustrcpy(crp, kbuf, s.arg1);            
  1273.             kumemcpy(crp, &temps, s.arg2, sizeof(temps));
  1274.             crp->result = utimes(kbuf, &temps);
  1275.             break;
  1276.             }
  1277.         case SYS_getrlimit:
  1278.             {
  1279.             struct rlimit klimit;
  1280.             crp->result = getrlimit(s.arg1, &klimit);
  1281.             ukmemcpy(crp, s.arg2, &klimit, sizeof(struct rlimit));
  1282.             break;
  1283.             }
  1284.         case SYS_setrlimit:
  1285.             {
  1286.             struct rlimit klimit;
  1287.             kumemcpy(crp, &klimit, s.arg2, sizeof(struct rlimit));
  1288.             crp->result = setrlimit(s.arg1, &klimit);
  1289.             break;
  1290.             }
  1291.         case SYS_getdirentries:
  1292.             {
  1293.             long actualsize;
  1294.             char *kbuf = xmalloc(s.arg3);
  1295.             if ((s.arg1<0)||(s.arg1>OPEN_MAX)||!crp->fd_tab[s.arg1]) crp->result = -1;
  1296.             else crp->result = getdirentries(crp->fd_tab[s.arg1], kbuf, s.arg3, &actualsize);
  1297.             ukmemcpy(crp, s.arg2, kbuf, s.arg3);
  1298.             ukmemcpy(crp, s.arg4, &actualsize, sizeof(long));
  1299.             break;
  1300.             }
  1301.         }
  1302.      if (debug && (crp->result==-1))
  1303.          {
  1304.          kprintf("Failed system call %s(%X,%X,%X)\n", callname(crp->registers.save[0]), s.arg1, s.arg2, s.arg3);
  1305.          }
  1306.     /* save crp->result of system call */
  1307.     if (crp->state == 'R')
  1308.         {
  1309.         enum {carry=1};
  1310.         if (crp->result==-1)
  1311.             {
  1312.             crp->registers.save[0] = errno;
  1313.             crp->registers.flags |= carry;
  1314.             }
  1315.         else
  1316.             {
  1317.             crp->registers.save[0] = crp->result;
  1318.             crp->registers.flags &= ~carry;
  1319.             }
  1320. //        crp->registers.save[1] = 0;    /* is this correct ? */
  1321.         }
  1322.     }
  1323.  
  1324.